package zsc.ruanc.practicaltraining.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.spring.web.json.Json;
import zsc.ruanc.practicaltraining.exception.ApiException;
import zsc.ruanc.practicaltraining.model.domain.TStatistic;
import zsc.ruanc.practicaltraining.model.result.JsonResult;
import zsc.ruanc.practicaltraining.model.vo.ArticleVo;
import zsc.ruanc.practicaltraining.model.vo.TimeVo;
import zsc.ruanc.practicaltraining.model.vo.UpdateArticleVo;
import zsc.ruanc.practicaltraining.service.ArticleService;
import zsc.ruanc.practicaltraining.service.RabbitMQService;
import zsc.ruanc.practicaltraining.utils.PrintfUtils;
import zsc.ruanc.practicaltraining.utils.ResultUtils;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.Map;

/**
 * 文章控制器
 */
@RestController
@RequestMapping("/article")
@Validated
@Api(tags = "文章模块/对文章的所有操作")
public class ArticleController {

    @Autowired
    private ArticleService articleService;

    @Autowired
    private RabbitMQService rabbitMQService;

    @ApiOperation(value = "新建文章", httpMethod = "POST")
    @PostMapping("/insert")
    public JsonResult insetrArticle(@Validated @RequestBody ArticleVo vo, HttpServletRequest httpServletRequest) {
        PrintfUtils.print(vo); // 打印请求信息
        return ResultUtils.success(articleService.insert(vo, (int)httpServletRequest.getAttribute("id")), "上传成功，请等待管理员审核");
    }

    @GetMapping("/delete/{id}")
    @ApiOperation(value = "删除文章(管理员 普通用户共用)", httpMethod = "GET")
    public JsonResult deleteArticle(@Min(message = "参数不能小于1", value = 1) @NotNull(message = "条件不能为空") @PathVariable(value = "id") Integer id, HttpServletRequest httpServletRequest) {
        String role = (String) httpServletRequest.getAttribute("role");

        if (role.equals("ROLE_admin")) {
            return ResultUtils.success(articleService.delete(id, null), "删除成功");
        } else {
            return ResultUtils.success(articleService.delete(id, (int)httpServletRequest.getAttribute("id")), "删除成功");
        }


    }

    @GetMapping("/userArticleList")
    @ApiOperation(value = "获得一个用户的所有文章（分页）", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cur", value = "当前页", dataType = "Integer", paramType = "query", defaultValue = "1"),
            @ApiImplicitParam(name = "size", value = "页大小", dataType = "Integer", paramType = "query", defaultValue = "10"),
            @ApiImplicitParam(name = "id", value = "查询条件 对方id", dataType = "Integer", paramType = "query")
    })
    public JsonResult userList(@Min(message = "参数cur不能小于0", value = 0) @RequestParam(value = "cur", defaultValue = "1") Integer cur,
                               @Min(message = "参数size不能小于1", value = 1) @RequestParam(value = "size", defaultValue = "10") Integer size,
                               @Min(message = "参数id不能小于1", value = 1) @NotNull(message = "条件不能为空") @RequestParam(value = "id", required = false) Integer id) {
        return ResultUtils.success(articleService.selectPageByUser(id, cur, size, true));
    }


    @GetMapping("/getAllTrue")
    @ApiOperation(value = "获得所有已审核的文章（分页）", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cur", value = "当前页", dataType = "Integer", paramType = "query", defaultValue = "1"),
            @ApiImplicitParam(name = "size", value = "页大小", dataType = "Integer", paramType = "query", defaultValue = "10")
    })
    public JsonResult getAllTrue(@Min(message = "参数cur不能小于0", value = 0) @RequestParam(value = "cur", defaultValue = "1") Integer cur,
                               @Min(message = "参数size不能小于1", value = 1) @RequestParam(value = "size", defaultValue = "10") Integer size) {
        return ResultUtils.success(articleService.selectAll(cur, size, true));
    }


    @GetMapping("/get/{id}")
    @ApiOperation(value = "获得一篇文章(只能获得已审核的文章，不需要token)", httpMethod = "GET")
    public JsonResult get(@Min(message = "参数不能小于1", value = 1) @NotNull(message = "条件不能为空") @PathVariable(value = "id") Integer id) {
        return ResultUtils.success(articleService.getArticle(id, null));
    }

    @GetMapping("/getMeArticle/{id}")
    @ApiOperation(value = "获得自己一篇文章(管理员、普通用户公用)", httpMethod = "GET")
    public JsonResult getme(@Min(message = "参数不能小于1", value = 1) @NotNull(message = "条件不能为空") @PathVariable(value = "id") Integer id, HttpServletRequest httpServletRequest) {
        String role = (String) httpServletRequest.getAttribute("role");
        if (role.equals("ROLE_admin")) { // 管理员无条件
            return ResultUtils.success(articleService.getArticle(id, -1));
        }
        Integer userId = (Integer) httpServletRequest.getAttribute("id");
        return ResultUtils.success(articleService.getArticle(id, userId));
    }

    @GetMapping("/myselfArticleList")
    @ApiOperation(value = "自己获取自己发布过的文章（分页）", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cur", value = "当前页", dataType = "Integer", paramType = "query", defaultValue = "1"),
            @ApiImplicitParam(name = "size", value = "页大小", dataType = "Integer", paramType = "query", defaultValue = "10"),
            @ApiImplicitParam(name = "flag", value = "查询条件(null：全部|true：已审核|false：未审核)", dataType = "Boolean", paramType = "query", defaultValue = "null")
    })
    public JsonResult getMyself(@Min(message = "参数cur不能小于0", value = 0) @RequestParam(value = "cur", defaultValue = "1") Integer cur,
                                @Min(message = "参数cur不能小于1", value = 1) @RequestParam(value = "size", defaultValue = "10") Integer size,
                                @RequestParam(value = "flag", required = false) Boolean flag,
                                HttpServletRequest httpServletRequest) {
        int id = (int)httpServletRequest.getAttribute("id");
        return ResultUtils.success(articleService.selectPageByUser(id, cur, size, flag));
    }

    @GetMapping("/vagueQuery")
    @ApiOperation(value = "模糊查询（分页）", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cur", value = "当前页", dataType = "Integer", paramType = "query", defaultValue = "1"),
            @ApiImplicitParam(name = "size", value = "页大小", dataType = "Integer", paramType = "query", defaultValue = "10"),
            @ApiImplicitParam(name = "text", value = "查询条件", dataType = "String", paramType = "query")
    })
    public JsonResult vagueQuery(@RequestParam(value = "text", required = false) String text,
                                 @Min(message = "参数cur不能小于0", value = 0) @RequestParam(value = "cur", defaultValue = "1") Integer cur,
                                 @Min(message = "参数size不能小于1", value = 1) @RequestParam(value = "size", defaultValue = "10") Integer size) {
        return ResultUtils.success(articleService.selectPage(text, cur, size));
    }

    @PostMapping("/update")
    @ApiOperation(value = "更新文章", httpMethod = "POST")
    public JsonResult updateArticle(@Validated @RequestBody UpdateArticleVo vo, HttpServletRequest httpServletRequest) {
        PrintfUtils.print(vo); // 打印请求信息

        int id = (int) httpServletRequest.getAttribute("id");
        return ResultUtils.success(articleService.updateArticle(vo, id), "更新成功");
    }

    @GetMapping("/setAllow")
    @ApiOperation(value = "设置文章是否可评论", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "文章id", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "flag", value = "true可评论 | false不可评论", dataType = "Boolean", paramType = "query")
    })
    public JsonResult setAllow(@Min(message = "参数不能小于1", value = 1) @NotNull(message = "文章id不能为空") @RequestParam(value = "id", required = false) Integer id,
                               @NotNull(message = "你想要干嘛") @RequestParam(value = "flag", required = false) Boolean flag,
                               HttpServletRequest httpServletRequest) {
        return ResultUtils.success(articleService.updateAllow(id, flag, (int)httpServletRequest.getAttribute("id")), "设置成功");
    }



    @GetMapping("/likes/{articleId}")
    @ApiOperation(value = "文章点赞|取消点赞", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "articleId", value = "操作文章id", dataType = "Integer", paramType = "path"),
            @ApiImplicitParam(name = "flag", value = "true点赞|false取消点赞", dataType = "Boolean", paramType = "query")
    })
    public JsonResult likes(@Min(message = "参数不能小于1", value = 1) @NotNull(message = "文章id不能为空") @PathVariable(value = "articleId", required = false) Integer articleId,
                            @NotNull(message = "状态不能为空") @RequestParam(value = "flag", required = false) Boolean flag,
                            HttpServletRequest httpServletRequest) {

        int userId = (int)httpServletRequest.getAttribute("id");
        String name = (String) httpServletRequest.getAttribute("name");

        if (flag == true) {
            articleService.likesAndOne(articleId);
            rabbitMQService.likesMailbox(userId, name, articleId); // 提醒作者文章被点赞
        } else {
            articleService.likesCutOne(articleId);
        }

        return ResultUtils.success();
    }

    @GetMapping("/recommend")
    @ApiOperation(value = "系统推荐文章", httpMethod = "GET")
    public JsonResult recommend(@Min(message = "row要大于1", value = 1) @RequestParam(value = "row", defaultValue = "5") Integer row,
                                @Min(message = "condition要大于1", value = 1) @Max(message = "不能大于3", value = 3)@RequestParam(value = "condition", defaultValue = "1")Integer condition) {
        String orderColumn = null;
        if (condition == 1) {
            orderColumn = "hits";
        } else if (condition == 2) {
            orderColumn = "comments_num";
        } else if (condition == 3) {
            orderColumn = "likes";
        }
        return ResultUtils.success(articleService.recommendList(row, orderColumn));
    }


    @GetMapping("/articleAnalysis")
    @ApiOperation(value = "文章统计分析", httpMethod = "GET")
    public JsonResult articleAnalysis(HttpServletRequest httpServletRequest) {
        int userId = (int) httpServletRequest.getAttribute("id");
        return ResultUtils.success(articleService.articleAnalysis(userId));
    }


    @GetMapping("/selectCategories")
    @ApiOperation(value = "按分类查询(分页)", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cur", value = "当前页", dataType = "Integer", paramType = "query", defaultValue = "1"),
            @ApiImplicitParam(name = "size", value = "页大小", dataType = "Integer", paramType = "query", defaultValue = "10"),
            @ApiImplicitParam(name = "categories", value = "按分类查询", dataType = "categories", paramType = "query")
    })
    public JsonResult adminSelect(@NotBlank(message = "条件不能为空") @RequestParam(value = "categories", required = false) String categories,
                                  @Min(message = "参数cur不能小于0", value = 0) @RequestParam(value = "cur", defaultValue = "1") Integer cur,
                                  @Min(message = "参数size不能小于1", value = 1) @RequestParam(value = "size", defaultValue = "10") Integer size) {
        return ResultUtils.success(articleService.selectByCategories(cur, size, categories));
    }


    //---------管理员权限----------------------------------------

    @GetMapping("/setFlag")
    @ApiOperation(value = "管理员审核文章(管理员权限)", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "文章id", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "flag", value = "true过审核 | false未审核", dataType = "Boolean", paramType = "query")
    })
    public JsonResult setFlag(@Min(message = "参数不能小于1", value = 1) @NotNull(message = "文章id不能为空") @RequestParam(value = "id", required = false) Integer id,
                              @NotNull(message = "你想要干嘛") @RequestParam(value = "flag", required = false) Boolean flag) {
        articleService.updateFlag(id, flag);

        rabbitMQService.verifyMailbox(id, flag); // 通知作者

        return ResultUtils.success(true, "OK");
    }

    @PostMapping("/adminSelect")
    @ApiOperation(value = "查询文章(查询条件：时间、审核)(管理员|分页)", httpMethod = "POST")

    public JsonResult adminSelect(@Validated @RequestBody TimeVo vo) {
        return ResultUtils.success(articleService.selectByTime(vo));
    }

    @GetMapping("/getCount")
    @ApiOperation(value = "获得文章数量(管理员权限)", httpMethod = "GET")
    @ApiImplicitParam(name = "flag", value = "查询条件(null：查询全部|true：查询已审核的文章|false:查询未审核的文章)", dataType = "Boolean", paramType = "query")
    public JsonResult getCount(@RequestParam(value = "flag", required = false) Boolean flag) {
        int x = articleService.articleCount(flag);
        Map map = new HashMap();
        map.put("num", x);
        return ResultUtils.success(map);
    }

    @PostMapping("/setInitialValue")
    @ApiOperation(value = "设置文章点赞、阅读量、评论量的初始值(管理员权限)", httpMethod = "POST")
    public JsonResult setValue(@Validated @RequestBody TStatistic vo) {
        return ResultUtils.success(articleService.updateStatistic(vo), "更改成功");
    }



}
